home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-02-19 | 4.4 KB | 120 lines | [TEXT/EDIT] |
-
-
- This is a C function that splits a region into its constituent
- rectangles for processing, plus a sample program to demonstrate it
- in action. If you are interested in this sort of thing, or already
- have such code and want to compare implementations, read on.
-
- You should have:
-
- README: you're reading it.
-
- EachRegionRect.c: the actual function
-
- RegionToRectangles.c: the demonstration program source code
-
- RegionToRectangles: compiled demonstration program
-
- I wrote this code just to see if I could figure out how regions
- worked rather than from any particular need. This meant that the
- straightforward approach - disassembling the Toolbox - was not on.
- What would be the fun in that? Bear with me through a somewhat
- rambling design process, or just look at the actual code if
- impatient.
-
- First, I wrote a little program to create various regions and did
- some poking around with the data structure. For those who haven't
- tried this, Quickdraw regions are stored as a list of horizontal
- edges. For instance, a H shape would look like:
-
-
- ---- ----
-
- ----
-
- ----
-
- ---- ----
-
-
- The actual data is divided into scan lines, each of which has a Y
- value, one or more X1 X2 pairs, and is terminated by 32767. The
- region ends with a scan line with Y value 32767. Continuing with
- the H example, the data looks like
-
- 0 0 32 64 96 32767
- 32 32 64 32767
- 64 32 64 32767
- 96 0 32 64 96 32767
- 32767
-
- Next I tried to get some idea of how to go about it in the good
- book: "Computer Graphics Principles and Practice." This has a
- chapter on Shapes, which are just regions under a new name but
- implemented differently. A further reference, "How to Color in a
- Coloring Book" by Henry Lieberman, turned out to be a seed filling
- (paint bucket) algorithmn but dealt with similar data.
-
- After some false starts, a reasonable algorithmn seemed to be
- this:
-
- * Begin a list of top edges for rectangles. The X pairs in the
- first scan line will all qualify.
-
- * Each subsequent X pair on a scan line is compared to the top
- edges on this list.
-
- * If it overlaps (ie is underneath) we have a matching bottom
- edge. Process the rectangle and remove the top from the list.
-
- * If it doesn't overlap, it is a new top edge. Add to the list.
-
- * A partial overlap is processed by splitting one or both edges
- into pieces, and applying the overlap test to each individual
- segment.
-
- At this point I was ready to start coding, and spent a couple of
- hours thinking about how to maintain this list of Y X1 X2 edges.The
- special case of a partial overlap looked like a real pain: the
- code would need to be able to delete an existing edge and replace
- it with two new ones.
-
- It then occurred to me that all these edges are just run length
- encodings of Y, so why not "uncompress" them? No two edges can
- share the same X value: if they did they would be overlapping and
- by the algorithmn would have to be processed and split until they
- didn't. So, all I really needed was an array to store the Y value
- for each possible X. Most regions are not going to be bigger than
- the screen, and even a giant monitor is 1024 pixels = only 2K of
- memory. I therefore decided to use a local array that stores a top
- edge for every pixel, with heap allocation in emergencies.
-
- NOTES:
-
- Macs with 68000 processors have an 8K stack by default and those
- with 68020 or better 24K. A 2K local array won't make much of a
- dent, but you could reduce the #define StackMax value if you are
- worried about the smaller machines.
-
- The code is (obviously) in C, because that's the language I've
- been working with lately. I can't see any reason why it couldn't
- be in Pascal if you prefer, although the switch between stack and
- heap storage would be messier. An assembly language implementation
- could be really neat: minimum stack usage, etc.
-
- This particular program was developed under THINK C version 5, and
- moved unchanged to version 6.
-
- The code uses an index to step through the region data rather than
- a pointer. This is because Quickdraw allocates regions itself
- rather than through the Memory Manager and there doesn't seem to
- be any way to lock them.
-
- There is an aesthetic problem with this code if used for screen
- updates. The rectangles are processed in Y-X order on the _bottom_
- edges, which as the demo program will show looks a bit peculiar.
- For screen updating you should use the code to build a list of
- rectangles, then sort them by top edge before drawing. This, as
- the textbooks say, is left as an exercise for the reader.
-
-